/*
 * CPlayStyle.java
 * 
 * Copyright (c) 2009 Giles Millward (Manigra). All rights reserved.
 * 
 * This file is part of JRogueDPS.
 * 
 * JRogueDPS is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * JRogueDPS is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with JRogueDPS.  If not, see <http://www.gnu.org/licenses/>.
 */

/* The playstyle syntax is taken directly from SimulationCraft
 *
 * http://code.google.com/p/simulationcraft/
 *
 * Thank you to Nate for giving permission to use the syntax within
 * JRogueDPS.
 */

package playstyle;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JCheckBox;
import javax.swing.JTextArea;
import javax.swing.text.BadLocationException;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentFactory;
import org.dom4j.Element;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;
import playstyle.CAbilityType.Ability;
import utility.CUtility;

/**
 *
 * @author Giles Millward (Manigra)
 */
public class CPlayStyle {
    private JCheckBox m_murderable;
    private JTextArea m_playStyleText;

    public void init(JCheckBox p_murderable, JTextArea p_playStyleText)
    {
        m_playStyleText = p_playStyleText;
        m_murderable = p_murderable;
    }

    public void testButton()
    {
        parse_text();
    }

    private int parse_text()
    {
        for (int i = 0; i < this.m_playStyleText.getLineCount(); i++)
        {
            String l_rawText = this.getPlayStyleLineText(i);

            if (l_rawText == null)
            {
                continue;
            }

            l_rawText = l_rawText.trim();
            
            if (l_rawText.equals(""))
            {
                continue;
            }

            // Strip comments
            if (l_rawText.startsWith("--") ||
                l_rawText.startsWith("#"))
            {
                continue;
            }

            if (l_rawText.contains("#"))
            {
                l_rawText = l_rawText.substring(0, l_rawText.indexOf("#"));
                l_rawText = l_rawText.trim();
                if (l_rawText.equals(""))
                {
                    continue;
                }
            }


            if (l_rawText.contains("-"))
            {
                l_rawText = l_rawText.substring(0, l_rawText.indexOf("-"));
                l_rawText = l_rawText.trim();
                if (l_rawText.equals(""))
                {
                    continue;
                }
            }

            // Remove spaces
            l_rawText = l_rawText.replaceAll(" ", "");
            l_rawText = l_rawText.toLowerCase();
            if (parse_raw_line(l_rawText) != true)
            {
                return i + 1;
            }
        }

        return 0;
    }

    private boolean parse_raw_line(String p_rawText)
    {
        // We want to add a new action and its constraints to the list
        String l_tokens[] = p_rawText.split(",");

        // First token should be the ability that will be used if the
        // conditions (following tokens) are met
        return true;
    }


    // Gets the raw text from a line with carriage return stripped
    private String getPlayStyleLineText(int l_line)
    {
        int l_start = 0;
        try {
            l_start = this.m_playStyleText.getLineStartOffset(l_line);
        } catch (BadLocationException ex) {
            Logger.getLogger(CPlayStyle.class.getName()).log(Level.SEVERE, null, ex);
        }
        int l_end = 0;
        try {
            l_end = this.m_playStyleText.getLineEndOffset(l_line);
        } catch (BadLocationException ex) {
            Logger.getLogger(CPlayStyle.class.getName()).log(Level.SEVERE, null, ex);
        }
        try {
            return (this.m_playStyleText.getText(l_start, Math.max((l_end - l_start) - 1, 0)));
        } catch (BadLocationException ex) {
            Logger.getLogger(CPlayStyle.class.getName()).log(Level.SEVERE, null, ex);
        }

        return null;
    }

    public void save()
    {
        String l_string = CUtility.openXMLFileSaveDialog("playstyles", "Set a filename for this play style");
        if (l_string == null)
        {
            return;
        }

        this.save(l_string);
    }

    public void save(String p_fileName) {
        Document doc = DocumentFactory.getInstance().createDocument();
        Element root = doc.addElement("root");
        this.addXMLData(root);

        if (!p_fileName.endsWith(".xml"))
        {
            p_fileName = p_fileName + ".xml";
        }

        FileOutputStream fos;
        try {
            fos = new FileOutputStream(p_fileName);
            OutputFormat format = OutputFormat.createPrettyPrint();
            XMLWriter writer;
            try {
                writer = new XMLWriter(fos, format);
                try {
                    writer.write(doc);
                    writer.flush();
                    writer.close();
                } catch (IOException ex) {
                    Logger.getLogger(CPlayStyle.class.getName()).log(Level.SEVERE, null, ex);
                }

            } catch (UnsupportedEncodingException ex) {
                Logger.getLogger(CPlayStyle.class.getName()).log(Level.SEVERE, null, ex);
            }

        } catch (FileNotFoundException ex) {
            Logger.getLogger(CPlayStyle.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    public void addXMLData(Element p_root)
    {
        Element l_playStyle = p_root.addElement("playstyle").
                addAttribute("murderable", CUtility.boolToString(m_murderable.isSelected()));
    }

    public void read()
    {
        String l_string = CUtility.openXMLFileOpenDialog("playstyles", "Choose a play style data file");
        if (l_string == null)
        {
            return;
        }

        this.read(l_string);
    }

    public void read(String l_fileName)
    {
        System.out.println("File String " + l_fileName);

        File l_xml = new File(l_fileName);

        SAXReader l_reader = new SAXReader();
        Document l_doc;
        try {
            l_doc = l_reader.read(l_xml);
            Element l_element = (Element) l_doc.selectSingleNode( "//root/playstyle" );
            this.parseXMLElement(l_element);
        } catch (DocumentException ex) {
            Logger.getLogger(CPlayStyle.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    public void parseXMLElement(Element p_element)
    {
        this.m_murderable.setSelected(CUtility.stringToBool(p_element.attributeValue("murderable")));
    }

    /**
     * @return the m_murderable
     */
    public boolean isMurderable() {
        return m_murderable.isSelected();
    }
}
